	import java.awt.Canvas;
	import java.awt.Color;
	import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
	import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Toolkit;
	import java.awt.event.KeyEvent;
	import java.awt.event.KeyListener;
	import java.awt.event.WindowAdapter;
	import java.awt.event.WindowEvent;
	import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
	import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Random;

import javax.imageio.ImageIO;
	import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
// Project: 

/******************************************************************************
 * <p>
 * File: retribution.java
 * </p>
 * @author  Tadhg O'Sullivan, rogue, Goncalo Bastos
 * @author <a href="mailto:tadhg.osullivan@ucdconnect.ie">tadhg.osullivan@ucdconnect.ie</a>
 * @version 1.0, 2007
 * @created 2-Mar-07 5:28:43 PM
 * @revised 
 * Copyright 2007 Tadhg O'Sullivan
 * <p>
 * Description: assigns coordinates to each tileObject and places them accordingly 
 * into a 2D array, returns a 2D array
 * Comment: Finished
 * </p>
 *  
 *  This file is part of Retribution.
 *
 *  Retribution is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  Retribution is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Retribution; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *   
 *****************************************************************************/

public class retribution extends Canvas implements KeyListener {
	
	// variables
	public String mainMapCoords = "1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,5,6,7,6,6,6,6,6,7,7,6,6,6,6,6,6,7,7,6,3,6,8,8,8,9,10,10,10,10,10,10,10,10,10,10,10,9,8,8,11,5,6,6,6,7,7,6,6,6,6,6,6,7,7,6,6,7,6,6,3,7,8,8,8,11,3,3,3,3,3,3,3,3,3,3,3,5,8,8,11,5,6,6,8,8,8,8,8,8,8,8,8,8,8,8,8,6,6,6,3,7,8,8,8,11,3,3,3,3,3,12,3,3,3,3,3,5,8,8,11,5,7,6,8,8,8,8,7,8,8,8,8,8,8,7,8,6,7,6,3,6,8,8,8,11,3,3,3,3,3,3,3,3,3,3,3,5,8,8,11,5,6,6,8,8,8,8,8,8,8,7,8,8,8,8,8,6,7,6,3,6,8,8,8,11,3,3,3,3,3,3,3,3,3,3,3,5,8,8,11,5,6,6,8,7,8,8,8,8,8,8,8,7,8,8,8,6,6,6,3,7,8,8,8,11,3,3,3,3,3,3,3,3,3,3,3,5,8,8,11,5,6,6,8,8,8,8,8,8,8,8,8,8,8,8,8,6,7,6,3,7,8,8,8,11,3,3,3,3,3,3,3,3,3,3,3,5,8,8,11,5,6,6,6,6,6,6,7,7,8,6,6,6,6,6,6,6,7,6,3,7,8,8,8,11,3,3,3,3,3,3,3,3,3,3,3,5,8,8,11,5,6,7,6,6,6,6,6,7,8,6,7,6,7,7,6,6,7,7,3,6,8,8,8,9,2,2,2,2,2,3,2,2,2,2,2,9,8,8,11,5,7,7,6,7,6,7,6,6,8,7,7,7,6,13,14,6,7,7,3,6,8,13,14,8,8,8,8,8,8,3,8,8,8,8,15,16,8,8,11,5,6,6,6,6,6,7,6,6,8,6,6,7,6,17,18,6,6,7,3,7,7,19,20,6,7,6,7,6,6,3,6,7,7,6,17,18,6,7,11,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5,6,6,6,6,7,6,6,6,8,6,6,6,6,6,6,6,7,6,3,7,6,6,7,7,6,7,7,6,7,6,7,6,7,7,6,8,6,7,6,5,7,7,6,6,7,6,6,8,8,8,6,6,7,7,7,6,7,6,3,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,6,7,7,5,6,6,6,6,6,6,8,8,8,8,8,6,6,6,7,6,6,6,3,7,8,6,6,6,6,7,7,7,6,6,7,7,6,6,6,7,6,7,6,5,6,6,9,9,9,8,8,8,8,8,8,8,9,9,9,6,15,16,3,6,8,8,8,8,8,8,8,8,8,8,7,8,8,8,8,8,8,8,6,5,7,7,9,9,8,8,8,8,8,8,8,8,8,9,9,7,19,20,3,6,6,6,6,6,6,7,6,6,8,8,7,8,8,8,21,8,8,8,7,5,7,6,9,9,8,8,8,8,8,8,8,8,8,9,9,7,6,3,3,6,7,7,7,7,7,6,6,6,8,8,6,8,8,8,8,8,8,8,7,5,7,6,9,8,8,8,8,8,8,8,8,8,8,8,9,6,7,6,3,6,6,6,6,7,6,6,6,6,8,8,6,8,8,8,8,8,8,8,7,5,6,6,9,9,8,8,8,8,8,8,8,8,8,9,9,6,6,6,3,7,8,8,8,8,8,8,8,8,8,8,6,8,8,8,8,8,8,8,6,5,6,6,9,9,9,8,8,8,8,8,8,8,9,9,9,6,7,6,3,7,8,6,6,6,7,7,6,6,7,6,7,8,8,8,8,8,8,8,7,5,7,7,6,9,9,9,9,9,22,9,9,9,9,9,6,7,7,7,3,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,7,5,6,6,7,6,9,9,9,9,9,9,9,9,9,6,6,7,6,7,3,6,7,7,6,6,7,6,7,6,6,6,6,8,8,8,8,8,8,8,6,23,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,3,6,6,7,7,6,6,6,6,7,6,6,6,6,6,6,6,6,6,6,6";
	public String mainHouseCoords = "1,8,8,8,8,9,3,6,6,6,6,5,3,6,6,6,11,5,3,6,6,6,6,5,3,10,6,6,6,5,7,4,4,4,4,2";
	public mapTile mapTiles;
	public hero heroTile;
	public enemy enemyTile;
	public npc npcTile;
	// linkedlist holding tile images
	public LinkedList<mapTile> ml;
	public LinkedList<mapTile> housel;
	public LinkedList<hero> hl;
	public LinkedList<enemy> el;
	public LinkedList<npc> nl;
	// 2d arrays for maps
	public mapTile mapTileArray[][];
	public mapTile houseTileArray[][];
	private BufferStrategy strategy;
	private long usedTime;
	public BufferedImage tile;
	public BufferedImage tile2;
	public cropTileset crop;
	public int mapHeigth = 800;
	public int mapWidth = 1280;
	public heroControl hc;
	public houseMovement hm;
	public enemyControl ec;
	public boolean paused = false;
	public JFrame retributionFrame;
	public int x = 0;
	public int y = 0;
	public int a = 0;
	public GameSounds gm;
	public boolean houseSound = false;
	public boolean mapSound = false;
	public boolean splashSound = false;
	public boolean gameStarted = false;
	public boolean gameEnded = false;
	public boolean menu = false;
	public boolean quit = false;
	public BufferedImage retImage = null;
	public BufferedImage chase1Image = null;
	public BufferedImage chase2Image = null;
	public int x1 = 0;
	public int x2 = - 128;
	public int y2 = mapHeigth - (mapHeigth / 3);
	public int i = 0;
	public int scaled = 8;
	Image splashImage;
	FontMetrics metrics;
	private int enemyHealth = 2;
	private int enemyPower = 1;
	private String name;
	private highScore high = new highScore();
	private int count;
	

		public retribution() {
			JOptionPane.showMessageDialog(null, "This game can only be played in a 1280*800 resolution");
			//Get the screen size
			Toolkit toolkit = Toolkit.getDefaultToolkit();
			Dimension screenSize = toolkit.getScreenSize();
			retributionFrame = new JFrame("Retribution");
			retributionFrame.addKeyListener(this);
			JPanel panel = (JPanel)retributionFrame.getContentPane();
			setBounds(0,0,mapWidth,mapHeigth);
			panel.setPreferredSize(new Dimension(mapWidth,mapHeigth));
			panel.setLayout(null);
			panel.add(this);
			retributionFrame.setBounds(0,0,mapWidth,mapHeigth);
			retributionFrame.setVisible(true);
			retributionFrame.addWindowListener( new WindowAdapter() {
				public void windowClosing(WindowEvent e) {
					System.exit(0);
				}
			});
			retributionFrame.setResizable(false);
			//Calculate the frame location
			int x = (screenSize.width - retributionFrame.getWidth()) / 2;
			int y = (screenSize.height - retributionFrame.getHeight()) / 2;
			retributionFrame.setLocation(x, y);
			retributionFrame.pack();
			setIgnoreRepaint(true);
			retributionFrame.addKeyListener(this);
			createBufferStrategy(5);
			strategy = getBufferStrategy();
			requestFocus();
			addKeyListener(this);
			name = JOptionPane.showInputDialog("What is your name?");
		}
		

		
		// initialise all the objects for the game
		public void initWorld() {
			Image scaledImage;
			crop = new cropTileset();
			hl = new LinkedList<hero>();
			hl = crop.importHeroTileset(0, 1);
			hl.get(0).setHealth(100);
			hl.get(0).setAttackStrength(1);
			el = new LinkedList<enemy>();
			el = crop.importEnemyTileset(0, 1, "skt.gif");
			el.get(0).setHealth(enemyHealth);
			el.get(0).setAttackStrength(enemyPower);
			el.addLast(crop.importEnemyTileset(0, 1, "skt.gif").get(0));
			el.get(1).setHealth(enemyHealth);
			el.get(1).setAttackStrength(enemyPower);
			el.addLast(crop.importEnemyTileset(0, 1, "skt.gif").get(0));
			el.get(2).setHealth(enemyHealth);
			el.get(2).setAttackStrength(enemyPower);
			enemyHealth += enemyHealth;
			enemyPower++;
			el.addLast(crop.importEnemyTileset(0, 1, "dvl.gif").get(0));
			el.get(3).setHealth(enemyHealth);
			el.get(3).setAttackStrength(enemyPower);
			el.addLast(crop.importEnemyTileset(0, 1, "dvl.gif").get(0));
			el.get(4).setHealth(enemyHealth);
			el.get(4).setAttackStrength(enemyPower);
			el.addLast(crop.importEnemyTileset(0, 1, "dvl.gif").get(0));
			el.get(5).setHealth(enemyHealth);
			el.get(5).setAttackStrength(enemyPower);
			enemyHealth += enemyHealth;
			enemyPower++;
			el.addLast(crop.importEnemyTileset(0, 1, "mnts.gif").get(0));
			el.get(6).setHealth(enemyHealth);
			el.get(6).setAttackStrength(enemyPower);
			el.addLast(crop.importEnemyTileset(0, 1, "mnts.gif").get(0));
			el.get(7).setHealth(enemyHealth);
			el.get(7).setAttackStrength(enemyPower);
			el.addLast(crop.importEnemyTileset(0, 1, "mnts.gif").get(0));
			el.get(8).setHealth(enemyHealth);
			el.get(8).setAttackStrength(enemyPower);
			enemyHealth += enemyHealth;
			enemyPower++;
			el.addLast(crop.importEnemyTileset(0, 1, "spd.gif").get(0));
			el.get(9).setHealth(enemyHealth);
			el.get(9).setAttackStrength(enemyPower);
			el.addLast(crop.importEnemyTileset(0, 1, "spd.gif").get(0));
			el.get(10).setHealth(enemyHealth);
			el.get(10).setAttackStrength(enemyPower);
			el.addLast(crop.importEnemyTileset(0, 1, "spd.gif").get(0));
			el.get(11).setHealth(enemyHealth);
			el.get(11).setAttackStrength(enemyPower);
			el.addLast(crop.importEnemyTileset(0, 1, "boss.gif").get(0));			
			el.get(el.size()-1).setHealth(75);
			el.get(el.size()-1).setAttackStrength(10);
			ml = new LinkedList<mapTile>();
			ml = crop.importMapTileset(0, 24);
			housel = new LinkedList<mapTile>();
			housel = crop.importHouseTileset(0, 11);
			String[] coords = mainMapCoords.split(",");
			int parsed = 0;
			mapTileArray = new mapTile[25][40];
			int coordsCount = 0;
			int posY = 0;
			int posX = 0;
			hl.get(0).setHouse(false);
			
			try {
				// get the tileset BufferedImage
			    retImage = ImageIO.read(this.getClass().getResource("title.gif"));
			} catch (IOException e) {
			}
			
			try {
				// get the tileset BufferedImage
			    chase1Image = ImageIO.read(this.getClass().getResource("boss.gif"));
			} catch (IOException e) {
			}
			
			try {
				// get the tileset BufferedImage
			    chase2Image = ImageIO.read(this.getClass().getResource("herort.gif"));
			} catch (IOException e) {
			}
			
			// create an array for the main map
			for(int i = 0; i < 200; i += 8){
				posX=0;
				for(int j = 0; j < 320; j += 8){
					parsed = Integer.parseInt(coords[coordsCount]);
					//System.out.println(parsed+","+coordsCount+","+coords[coordsCount]);
					ml.get(parsed - 1).setX(j);
					ml.get(parsed - 1).setY(i);
					tile = ml.get(parsed - 1).getBufferedImage();
					scaledImage = tile.getScaledInstance(8*(mapWidth/320),8*(mapHeigth/200), tile.SCALE_FAST);
					ml.get(parsed - 1).setImage(scaledImage);
					mapTileArray[posY][posX] = ml.get(parsed - 1);
					coordsCount++;
					posX++;
				}
				posY++;
			}
			
			mapTileArray[11][9] = ml.get(8);
			mapTileArray[13][9] = ml.get(8);
			mapTileArray[11][30] = ml.get(8);
			mapTileArray[13][36] = ml.get(8);

			
			// create a 2d array for the houses
			coords = mainHouseCoords.split(",");
			parsed = 0;
			coordsCount = 0;
			// create an array for a house
			houseTileArray = new mapTile[6][6];
			for(int i = 0; i < 6; i ++){
				for(int j = 0; j < 6; j ++){
					parsed = Integer.parseInt(coords[coordsCount]);
					//System.out.println(parsed+","+coordsCount+","+coords[coordsCount]);
					tile = housel.get(parsed - 1).getBufferedImage();
					scaledImage = tile.getScaledInstance(8*(mapWidth/320),8*(mapHeigth/200), tile.SCALE_FAST);
					housel.get(parsed - 1).setImage(scaledImage);
					houseTileArray[i][j] = housel.get(parsed - 1);
					houseTileArray[i][j].setX((j + 9) * mapWidth/40);
					houseTileArray[i][j].setY((i + 11) * mapHeigth/25);
					coordsCount++;
				}
			}

			// set up the sprite images
			tile = hl.get(0).getBufferedImage();
			scaledImage = tile.getScaledInstance(8*(mapWidth/320),8*(mapHeigth/200), tile.SCALE_FAST);
			hl.get(0).setX((8*(mapWidth/320) * 19));
			hl.get(0).setY(mapHeigth - 8*(mapWidth/320));
			tile = hl.get(0).getBufferedImage();
			scaledImage = tile.getScaledInstance(8*(mapWidth/320),8*(mapHeigth/200), tile.SCALE_FAST);
			hl.get(0).setImage(scaledImage);
			
			//top left quadrant
			el.get(0).setX((8*(mapWidth/320) * 11));
			el.get(0).setY(mapHeigth - mapHeigth + (8*(mapWidth/320) * 4));
			tile = el.get(0).getBufferedImage();
			scaledImage = tile.getScaledInstance(8*(mapWidth/320),8*(mapHeigth/200), tile.SCALE_FAST);
			el.get(0).setImage(scaledImage);
			
			el.get(1).setX((8*(mapWidth/320) * 8));
			el.get(1).setY(mapHeigth - mapHeigth + (8*(mapWidth/320) * 4));
			tile = el.get(1).getBufferedImage();
			scaledImage = tile.getScaledInstance(8*(mapWidth/320),8*(mapHeigth/200), tile.SCALE_FAST);
			el.get(1).setImage(scaledImage);
			
			el.get(2).setX((8*(mapWidth/320) * 4));
			el.get(2).setY(mapHeigth - mapHeigth + (8*(mapWidth/320) * 4));
			tile = el.get(2).getBufferedImage();
			scaledImage = tile.getScaledInstance(8*(mapWidth/320),8*(mapHeigth/200), tile.SCALE_FAST);
			el.get(2).setImage(scaledImage);
			
			// bottom right quadrant
			el.get(6).setX((8*(mapWidth/320) * 35));
			el.get(6).setY(mapHeigth - (8*(mapWidth/320) * 4));
			tile = el.get(6).getBufferedImage();
			scaledImage = tile.getScaledInstance(8*(mapWidth/320),8*(mapHeigth/200), tile.SCALE_FAST);
			el.get(6).setImage(scaledImage);
			
			el.get(7).setX((8*(mapWidth/320) * 36));
			el.get(7).setY(mapHeigth - (8*(mapWidth/320) * 4));
			tile = el.get(7).getBufferedImage();
			scaledImage = tile.getScaledInstance(8*(mapWidth/320),8*(mapHeigth/200), tile.SCALE_FAST);
			el.get(7).setImage(scaledImage);
			
			el.get(8).setX((8*(mapWidth/320) * 34));
			el.get(8).setY(mapHeigth - (8*(mapWidth/320) * 4));
			tile = el.get(8).getBufferedImage();
			scaledImage = tile.getScaledInstance(8*(mapWidth/320),8*(mapHeigth/200), tile.SCALE_FAST);
			el.get(8).setImage(scaledImage);
			
			// bottom left quadrant
			el.get(3).setX((8*(mapWidth/320) * 11));
			el.get(3).setY(mapHeigth - (8*(mapWidth/320) * 4));
			tile = el.get(3).getBufferedImage();
			scaledImage = tile.getScaledInstance(8*(mapWidth/320),8*(mapHeigth/200), tile.SCALE_FAST);
			el.get(3).setImage(scaledImage);
			
			el.get(4).setX((8*(mapWidth/320) * 10));
			el.get(4).setY(mapHeigth - (8*(mapWidth/320) * 4));
			tile = el.get(4).getBufferedImage();
			scaledImage = tile.getScaledInstance(8*(mapWidth/320),8*(mapHeigth/200), tile.SCALE_FAST);
			el.get(4).setImage(scaledImage);
			
			el.get(5).setX((8*(mapWidth/320) * 9));
			el.get(5).setY(mapHeigth - (8*(mapWidth/320) * 4));
			tile = el.get(5).getBufferedImage();
			scaledImage = tile.getScaledInstance(8*(mapWidth/320),8*(mapHeigth/200), tile.SCALE_FAST);
			el.get(5).setImage(scaledImage);
			
			// top right quadrant
			el.get(9).setX((8*(mapWidth/320) * 35));
			el.get(9).setY(mapHeigth - mapHeigth + (8*(mapWidth/320) * 4));
			tile = el.get(9).getBufferedImage();
			scaledImage = tile.getScaledInstance(8*(mapWidth/320),8*(mapHeigth/200), tile.SCALE_FAST);
			el.get(9).setImage(scaledImage);
			
			el.get(10).setX((8*(mapWidth/320) * 33));
			el.get(10).setY(mapHeigth - mapHeigth + (8*(mapWidth/320) * 4));
			tile = el.get(10).getBufferedImage();
			scaledImage = tile.getScaledInstance(8*(mapWidth/320),8*(mapHeigth/200), tile.SCALE_FAST);
			el.get(10).setImage(scaledImage);
			
			el.get(11).setX((8*(mapWidth/320) * 30));
			el.get(11).setY(mapHeigth - mapHeigth + (8*(mapWidth/320) * 5));
			tile = el.get(11).getBufferedImage();
			scaledImage = tile.getScaledInstance(8*(mapWidth/320),8*(mapHeigth/200), tile.SCALE_FAST);
			el.get(11).setImage(scaledImage);
			
			el.get(12).setX((8*(mapWidth/320) *30));
			el.get(12).setY(mapHeigth - mapHeigth + (8*(mapWidth/320) * 6));
			tile = el.get(12).getBufferedImage();
			scaledImage = tile.getScaledInstance(8*(mapWidth/320),8*(mapHeigth/200), tile.SCALE_FAST);
			el.get(12).setImage(scaledImage);
			
			tile = retImage;
			System.out.println(retImage.getHeight());
			System.out.println(retImage.getWidth());
			splashImage = tile.getScaledInstance(mapWidth - (mapWidth / 4),mapHeigth / 4, tile.SCALE_FAST);
			

	    }
		
		// update the world in the game lood
		public void updateWorld() {
			Graphics2D g = (Graphics2D)strategy.getDrawGraphics();
			// if hero enters house update
			if((mapTileArray[hl.get(0).getY() / (8*(mapWidth/320))][hl.get(0).getX() / (8*(mapWidth/320))].getHouse() > 0) || (hl.get(0).getHouse() == true)){
				hm = new houseMovement();
				if(hl.get(0).getHouse() != true){
					if(hl.get(0).getX() / (8*(mapWidth/320)) == 15){
						a = 2;
					}else if(hl.get(0).getX() / (8*(mapWidth/320)) == 23){
						a = 3;
					}else if(hl.get(0).getX() / (8*(mapWidth/320)) == 36){
						a = 4;
					}else{
						a = 1;
					}
				x = hl.get(0).getX();
				y = hl.get(0).getY();
				hl.get(0).setY(houseTileArray[5][5].getY());
				hl.get(0).setX(houseTileArray[5][5].getX());
				try {
					gm.DoorCreak();
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				}
				hl.get(0).setHouse(true);
				hm.moveHero(hl.get(0), houseTileArray, a, x, y, mapHeigth,el);
			// else update the sprite movements
			}else{
				hc = new heroControl();
				ec = new enemyControl();
				hc.moveHero(el, hl.get(0), mapTileArray, mapHeigth);
				if(hl.get(0).getAttackState()){
					hl.get(0).setAttackState(false);
				}
				//if(hl.get(0).getMovedState()){
					for(int i = 0; i < 13; i++){
						if(el.get(i).getLifeState()){
							ec.moveEnemy(el,hl.get(0), el.get(i), mapTileArray, mapHeigth);
							if(el.get(i).getAttackState()){
								el.get(i).setAttackState(false);
							}
						}
					}
				//}
				hl.get(0).setMovedState(false);
			}
			count = 0;
			for(int i=0;i<el.size();i++){
				if(!el.get(i).getLifeState()){
					count++;
				}
			}
			if(count==el.size()){
				Font f2 = new Font("Courier", Font.BOLD,100);
				g.setFont(f2);
				g.drawString("CONGRATULATIONS", mapHeigth/2, mapWidth/2);
				quit=true;
			}
		}
		
		// draw to the screen
		public void paintWorld() {
			Graphics2D g = (Graphics2D)strategy.getDrawGraphics();
			g.setColor(Color.black);
			g.fillRect(0,0,getWidth(),getHeight());
			Font f = new Font("Courier", Font.BOLD,  (8*(mapWidth/320)) / 2);
			metrics = g.getFontMetrics();

			Image woman = null;
			
			// if in the house...
			if(hl.get(0).getHouse() == true){
				if(a ==1){
					mapTileArray[11][9] = ml.get(7);	
					g.setFont(f);
					g.setColor(Color.RED);
					g.drawString("Hairy Butcher: Welcome to my hovel mighty monkey hero,",(mapWidth / 2) - metrics.stringWidth("Hairy Butcher: Welcome to my hovel mighty monkey hero,"), mapHeigth - (mapHeigth / 8));
					g.drawString("Hairy Butcher: rest for a while and heal you wounds,",(mapWidth / 2) - metrics.stringWidth("Hairy Butcher: rest for a while and heal you wounds,"), mapHeigth - (mapHeigth / 8) + 20);
					g.drawString("Hairy Butcher: and please kill those stubid skeletons in the North West orchard.",(mapWidth / 2) - metrics.stringWidth("Hairy Butcher: and please kill those stubid skeletons in the North West orchard."), mapHeigth - (mapHeigth / 8) + 40);
					g.drawString("Hairy Butcher: Oh, and come back any time to rest and recover your strength.",(mapWidth / 2) - metrics.stringWidth("Hairy Butcher: Oh, and come back any time to rest and recover your strength."), mapHeigth - (mapHeigth / 8) + 60);
				}else if(a == 2){
					mapTileArray[13][9] = ml.get(7);
					g.setFont(f);
					g.setColor(Color.PINK);
					g.drawString("Lusty Wench: Welcome to my hovel studmuffin,",(mapWidth / 2) - metrics.stringWidth("Lusty Wench: Welcome to my hovel studmuffin,"), mapHeigth - (mapHeigth / 8));
					g.drawString("Lusty Wench: why not rest and let me give you a sensual massage,",(mapWidth / 2) - metrics.stringWidth("Lusty Wench: why not rest and let me give you a sensual massage,"), mapHeigth - (mapHeigth / 8) + 20);
					g.drawString("Lusty Wench: and after you can clear the field near the cave in the South West.the deamons are blocking my sanctuary.",(mapWidth / 2) - metrics.stringWidth("Lusty Wench: and after you can clear the field near the cave in the South West.the deamons are blocking my sanctuary."), mapHeigth - (mapHeigth / 8) + 40);
					g.drawString("Lusty Wench: Oh, and come back any time to rest and recover your strength.",(mapWidth / 2) - metrics.stringWidth("Lusty Wench: Oh, and come back any time to rest and recover your strength."), mapHeigth - (mapHeigth / 8) + 60);
				}else if(a == 3){
					mapTileArray[13][36] = ml.get(7);
					g.setFont(f);
					g.setColor(Color.RED);
					g.drawString("Young Girl: Hello I need your help,",(mapWidth / 2) - metrics.stringWidth("Young Girl: Hello I need your help,"), mapHeigth - (mapHeigth / 8));
					g.drawString("Young Girl: My mother has been taken by the deamons ,",(mapWidth / 2) - metrics.stringWidth("Young Girl: My mother has been taken by the deamons ,"), mapHeigth - (mapHeigth / 8) + 20);
					g.drawString("Young Girl: You need to restore honour to my family, i saw them in the South East corner near the maze.",(mapWidth / 2) - metrics.stringWidth("Young Girl: You need to restore honour to my family, i saw them in the South East corner near the maze."), mapHeigth - (mapHeigth / 8) + 40);
					g.drawString("Young Girl: Oh, and come back any time to rest and recover your strength.",(mapWidth / 2) - metrics.stringWidth("Young Girl: Oh, and come back any time to rest and recover your strength."), mapHeigth - (mapHeigth / 8) + 60);
				}else if(a == 4){					
					mapTileArray[11][30] = ml.get(2);
					g.setFont(f);
					g.setColor(Color.RED);
					g.drawString("Old Woman: Hey there young buck,",(mapWidth / 2) - metrics.stringWidth("Old Woman: Hey there young buck,"), mapHeigth - (mapHeigth / 8));
					g.drawString("Old Woman: You look like you mean business. You're not much of a talker are you!,",(mapWidth / 2) - metrics.stringWidth("Old Woman: You look like you mean business. You're not much of a talker are you!,"), mapHeigth - (mapHeigth / 8) + 20);
					g.drawString("Old Woman: There's hoodlams up to no good in the North East Corner at the fountain.Go and make your self useful.",(mapWidth / 2) - metrics.stringWidth("Old Woman: There's hoodlams up to no good in the North East Corner at the fountain.Go and make your self useful."), mapHeigth - (mapHeigth / 8) + 40);
					g.drawString("Old Woman: Oh, and come back any time to rest and recover your strength.",(mapWidth / 2) - metrics.stringWidth("Old Woman: Oh, and come back any time to rest and recover your strength."), mapHeigth - (mapHeigth / 8) + 60);
				}
			for(int i=0;i<6;i++){
				for(int j=0;j<6;j++){
						g.drawImage(houseTileArray[i][j].getImage(), (j + 9) *mapWidth/40, (i + 11) * mapHeigth/25, null);
					}
			}
			try {
				// get the tileset BufferedImage
			    woman = ImageIO.read(this.getClass().getResource("wmn.gif"));
			} catch (IOException e) {
			}
			tile = (BufferedImage) woman;
			Image scaledImage = tile.getScaledInstance(8*((mapHeigth + (mapHeigth / 2) + ((mapHeigth / 100 ) * 10))/320),8 * (mapHeigth/200), tile2.SCALE_FAST);

			g.drawImage(scaledImage, houseTileArray[0][4].getX(), houseTileArray[0][4].getY(), null);
			
			g.drawImage(hl.get(0).getImage(), hl.get(0).getX(), hl.get(0).getY(), null);
			// else in normal map
			}else{
			
				for(int i=0;i<25;i++){
					for(int j=0;j<40;j++){
						g.drawImage(mapTileArray[i][j].getImage(), j *mapWidth/40, i * mapHeigth/25, null);
					}
				}
				if(hl.get(0).getLifeState()==true){
				g.drawImage(hl.get(0).getImage(), hl.get(0).getX(), hl.get(0).getY(), null);
				}else{
					Font f0nt = new Font("Courier", Font.BOLD,50);
					g.setFont(f0nt);
					g.drawString("GAME OVER", mapHeigth/2, mapWidth/2);
					quit = true;
					
				}
			
				for(int i = 0; i < 13; i++){
					if(el.get(i).getLifeState()==true)
						g.drawImage(el.get(i).getImage(), el.get(i).getX(), el.get(i).getY(), null);
					
				}
			}
			
			// the stats for the hero
			g.drawString("Health: " + hl.get(0).getHealth(),2,mapHeigth - mapHeigth + 12);
			g.drawString("Power: " + hl.get(0).getAttackStrength(),2,mapHeigth-mapHeigth +28);
			
			
			if (usedTime > 0)
			  g.drawString(String.valueOf(1000/usedTime)+" fps",2,mapHeigth-5);
			else
		  	g.drawString("--- fps",2,mapHeigth-5);
			strategy.show();
			
			g.dispose();
			strategy.show();
		}
		
		// key event listener
		public void keyTyped(KeyEvent e) {
			hl.get(0).keyTyped(e);
			ml.get(0).keyTyped(e);
			String keyHit = "";
				keyHit += e.getKeyChar();
			if(keyHit.equalsIgnoreCase("p")){
				if(paused == true){
					paused = false;
			}else{
				paused = true;
			}
	   	}
			if(keyHit.equalsIgnoreCase("m")){
				if(menu == false){
				menu = true;
				}else{
					menu = false;
				}
			}
			if(keyHit.equalsIgnoreCase("q")){
				if(quit == false){
				quit = true;
				}else{
					quit = false;
				}
			}
			int key = e.getKeyChar();
			if(key == KeyEvent.VK_ENTER){
				gameStarted = true;
			}
			keyHit = "";
		}
		
		// sound checker, make sure another sound is stopped or not playing before starting another
		public void startMapSound(){
			if(houseSound == true){
				gm.sequencer.stop();
			}
			if(mapSound == false){
			gm.main3Theme();
			mapSound = true;
			houseSound = false;
			}
		}
		
		// sound checker, make sure another sound is stopped or not playing before starting another
		public void startHouseSound(){
			if(mapSound == true){
				gm.sequencer.stop();
			}
			if(houseSound == false){
			gm.scaryTheme();
			mapSound = false;
			houseSound = true;
			}
		}
		
		// sound checker, make sure another sound is stopped or not playing before starting another
		public void pauseMusic(){
			if(mapSound == true){
				gm.sequencer.stop();
				mapSound = false;
			}
			if(houseSound == true){
				gm.sequencer2.stop();
				houseSound = false;
			}
		}
		
		// sound checker, make sure another sound is stopped or not playing before starting another
		public void splashMusic(){
			if(gameStarted == false){
				if(splashSound == false){
				gm.splashTheme();
				splashSound = true;
				}
			}
		}
		
		// sound checker, make sure another sound is stopped or not playing before starting another
		public void stopSplashMusic(){
			if((gameStarted == true) && (splashSound == true)){
				gm.sequencer.stop();
				splashSound = false;
				mapSound = false;
				startMapSound();
			}
		}
	
		
		public void keyPressed(KeyEvent arg0) {
			// TODO Auto-generated method stub
		}

		public void keyReleased(KeyEvent arg0) {
			// TODO Auto-generated method stub
		}
		
		// draw the splash screen
		public void splashScreen(){
			Graphics2D g = (Graphics2D)strategy.getDrawGraphics();
			g.setColor(Color.black);
			Font f = new Font("Courier", Font.BOLD,   (8*(mapWidth/320)) / 2);
			metrics = g.getFontMetrics();
			
			g.fillRect(0,0,getWidth(),getHeight());

			g.setFont(f);
			g.drawImage(splashImage, (mapWidth - splashImage.getWidth(this))/ 2, mapHeigth / 8, null);
			g.setColor(Color.WHITE);
			g.drawString("PRESS ENTER TO START GAME",(mapWidth / 2) - metrics.stringWidth("PRESS ENTER TO START GAME"), mapHeigth - (mapHeigth / 8));
			g.drawString("PRESS 'M' FOR MENU",(mapWidth / 2) - metrics.stringWidth("PRESS 'M' FOR MENU"), mapHeigth - (mapHeigth / 8) + 20);
			
				g.drawImage(chase1Image, x1, y2, null);
				g.drawImage(chase2Image, x2, y2, null);
				x1 += 32;
				x2 += 32;
				if(x1 >= 1280){
					x1 = 0;
				}
				if(x2 >= 1280){
					x2 = -128;
				}
				strategy.show();
				
				g.dispose();
				strategy.show();
		}
		
		// draw the menu screen
		public void menuScreen(){
			Graphics2D g = (Graphics2D)strategy.getDrawGraphics();
			Font f = new Font("Courier", Font.BOLD,   (8*(mapWidth/320)) / 2);
			metrics = g.getFontMetrics();
			g.setColor(Color.black);
			g.fillRect(0,0,getWidth(),getHeight());
			g.setFont(f);
			g.drawImage(splashImage,(mapWidth - splashImage.getWidth(this))/ 2, mapHeigth / 8, null);
			g.setColor(Color.RED);
			g.drawString("Keys:",(mapWidth / 2) - metrics.stringWidth("Keys:"), mapHeigth - (mapHeigth / 6) - 140);
			g.drawString("w = up",(mapWidth / 2) - metrics.stringWidth("Keys:"), mapHeigth - (mapHeigth / 6) - 120);
			g.drawString("s = down",(mapWidth / 2) - metrics.stringWidth("Keys:"), mapHeigth - (mapHeigth / 6) - 100);
			g.drawString("a = left",(mapWidth / 2) - metrics.stringWidth("Keys:"), mapHeigth - (mapHeigth / 6) - 80);
			g.drawString("d = right",(mapWidth / 2) - metrics.stringWidth("Keys:"), mapHeigth - (mapHeigth / 6) - 60);
			g.drawString("p = pause",(mapWidth / 2) - metrics.stringWidth("Keys:"), mapHeigth - (mapHeigth / 6) - 40);
			g.drawString("m = menu/return",(mapWidth / 2) - metrics.stringWidth("Keys:"), mapHeigth - (mapHeigth / 6) - 20);
			g.drawString("q = quit",(mapWidth / 2) - metrics.stringWidth("Keys:"), mapHeigth - (mapHeigth / 6));
			strategy.show();
			g.dispose();
			strategy.show();
		}
		
		// draw the menu screen
		public void introScreen(int i){
			Graphics2D g = (Graphics2D)strategy.getDrawGraphics();
			Font f = new Font("Courier", Font.BOLD,   (8*(mapWidth/320)) / 2);
			metrics = g.getFontMetrics();
			g.setColor(Color.black);
			g.fillRect(0,0,getWidth(),getHeight());
			
			g.drawImage(splashImage, (mapWidth - splashImage.getWidth(this))/ 2, mapHeigth / 8, null);
			g.setFont(f);
			g.setColor(Color.YELLOW);
			if(i < 250){
				g.drawString("In the Village of Oscillia far far away",(mapWidth / 2) - metrics.stringWidth("In the Village of Oscillia far far away"), mapHeigth- 140 - i);
				g.drawString("the rebel armies of hell are running wild.",(mapWidth / 2) - metrics.stringWidth("the rebel armies of hell are running wild"), mapHeigth - 120 - i);
				g.drawString("As our hero Nonam awakes from a slumber,",(mapWidth / 2) - metrics.stringWidth("As our hero Nonam awakes from a slumber"), mapHeigth - 100 - i);
				g.drawString("a demon stands over our hero ready to Attack,",(mapWidth / 2) - metrics.stringWidth("a demon stands over our hero ready to Attack,"), mapHeigth - 80 - i);
				g.drawString("Nonam plunges the sword through the torso of the demon and kills it.",(mapWidth / 2) - metrics.stringWidth("Nonam plunges the sword through the torso of the demon and kills it."), mapHeigth - 60 - i);
				g.drawString("Realising there may be more of these creatures lurking around the town,",(mapWidth / 2) - metrics.stringWidth("Realising there may be more of these creatures lurking around the town,"), mapHeigth - 40 - i);
				g.drawString("Nonam takes it upon himself to check up on the rest of the villagers and destroy the demons.",(mapWidth / 2) - metrics.stringWidth("Nonam takes it upon himself to check up on the rest of the villagers and destroy the demons."), mapHeigth - 20 - i);
				g.drawString(".....It begins.",(mapWidth / 2) - metrics.stringWidth("blah"), mapHeigth - i);
			}else{
				g.drawString("In the Village of Oscillia far far away",(mapWidth / 2) - metrics.stringWidth("In the Village of Oscillia far far away"), mapHeigth- 140 - 250);
				g.drawString("the rebel armies of hell are running wild.",(mapWidth / 2) - metrics.stringWidth("the rebel armies of hell are running wild"), mapHeigth - 120 - 250);
				g.drawString("As our hero Nonam awakes from a slumber,",(mapWidth / 2) - metrics.stringWidth("As our hero Nonam awakes from a slumber"), mapHeigth - 100 - 250);
				g.drawString("a demon stands over our hero ready to Attack,",(mapWidth / 2) - metrics.stringWidth("a demon stands over our hero ready to Attack,"), mapHeigth - 80 - 250);
				g.drawString("Nonam plunges the sword through the torso of the demon and kills it.",(mapWidth / 2) - metrics.stringWidth("Nonam plunges the sword through the torso of the demon and kills it."), mapHeigth - 60 - 250);
				g.drawString("Realising there may be more of these creatures lurking around the town,",(mapWidth / 2) - metrics.stringWidth("Realising there may be more of these creatures lurking around the town,"), mapHeigth - 40 - 250);
				g.drawString("Nonam takes it upon himself to check up on the rest of the villagers and destroy the demons.",(mapWidth / 2) - metrics.stringWidth("Nonam takes it upon himself to check up on the rest of the villagers and destroy the demons."), mapHeigth - 20 - 250);
				g.drawString(".....It begins.",(mapWidth / 2) - metrics.stringWidth(".....It begins."), mapHeigth - 250);
			}
			strategy.show();
			g.dispose();
			strategy.show();
		}
		
		// draw the credit screen
		public void creditScreen(){
			Graphics2D g = (Graphics2D)strategy.getDrawGraphics();
			Font f = new Font("Courier", Font.BOLD,   ((8*(mapWidth/320)) / 2) + 4);
			metrics = g.getFontMetrics();
			g.setColor(Color.black);
			g.fillRect(0,0,getWidth(),getHeight());
			g.drawImage(splashImage, (mapWidth - splashImage.getWidth(this))/ 2, mapHeigth / 8, null);
			g.setFont(f);
			g.setColor(Color.WHITE);
			g.drawString("CREDITS",(mapWidth / 2) - metrics.stringWidth("Credits"),  mapHeigth - (mapHeigth / 4) - 150);
			g.drawString("Programmer: Goncalo Bastos",(mapWidth / 2) - metrics.stringWidth("Programmer: Goncalo Bastos"),  mapHeigth - (mapHeigth / 4) - 125);
			g.drawString("Graphics: Tadhg O'Sullivan",(mapWidth / 2) - metrics.stringWidth("Graphics: Tadhg O'Sullivan"),  mapHeigth - (mapHeigth / 4) - 100);
			g.drawString("Audio/Testing: Brendan O'Huigin",(mapWidth / 2) - metrics.stringWidth("Audio/Testing: Brendan O'Huigin"),  mapHeigth - (mapHeigth / 4) - 75);
			g.drawString("Documentation/Testing: Sean Crowley",(mapWidth / 2) - metrics.stringWidth("Documentation/Testing: Sean Crowley"),  mapHeigth - (mapHeigth / 6) - 50);
			g.drawString("Web Design: Mikey Solomon",(mapWidth / 2) - metrics.stringWidth("Web Design: Mikey Solomon"),  mapHeigth - (mapHeigth / 4) - 25);
			g.drawString("Project Manager: Colm Mulryan",(mapWidth / 2) - metrics.stringWidth("Project Manager: Colm Mulryan"),  mapHeigth - (mapHeigth / 4));
			strategy.show();		
			g.dispose();
			strategy.show();
			Random ran = new Random();
			try {
				high.sendScore(name, Integer.toString(ran.nextInt(50000*count)));
			} catch (RuntimeException e) {
				high.sendScore(name, "1");
			}
			System.out.println(name);
		}
		
		// the game loop
		public void game() {
				usedTime=1000;
				initWorld();
				gm = new GameSounds();
				
				// while the jframe is visible
				while (isVisible()) {
					// quit if gameEnded == true
					if(gameEnded == false){
						
					// show menuScreen if menu == true
					if(menu == true){
						menuScreen();
						try { 
							 Thread.sleep(500);
						} catch (InterruptedException e) {}
					}
					
					// set gameEnded to true if q pressed
					if(quit == true){
						if(gameStarted == false){
						
						}else if(gameStarted == true){
							gameEnded = true;
						}
					}
					
					// start the splashScreen
					if((gameStarted == false) && (menu == false)){
						splashScreen();
						splashMusic();
						try { 
							 Thread.sleep(500);
						} catch (InterruptedException e) {}
					// start the main game
					}else if (menu == false){
						stopSplashMusic();
					if(paused == false){
						if((hl.get(0).getHouse() == false)){
						startMapSound();
						}
						if((hl.get(0).getHouse() == true)){
							startHouseSound();
						}
					long startTime = System.currentTimeMillis();
					if(i != 300){
						introScreen(i);
						i += 10;
					}else{
					updateWorld();
					paintWorld();
					}
					usedTime = System.currentTimeMillis()-startTime;
					try { 
						 Thread.sleep(500);
					} catch (InterruptedException e) {}
					}
					if(paused == true){
						pauseMusic();
					}
					}
					// show credits and close game
					}else{
						gm.sequencer.stop();
						gm.creditTheme();
						creditScreen();
						try {
							Thread.sleep(gm.sequencer.getMicrosecondLength() * 1000);
						} catch (InterruptedException e) {}
						System.exit(0);
					}
				}
		}
		
		// main method
		public static void main(String[] args) {
			retribution rt = new retribution();
			rt.game();

		}
}
